package handler

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"

	"hrms-api/model"
)

// ===== 角色相关结构体 =====

// RolePermissionRequest 角色权限请求结构
type RolePermissionRequest struct {
	RoleID       uint   `json:"role_id" binding:"required"`
	PermissionID []uint `json:"permission_ids" binding:"required"`
}

// UserRoleRequest 用户角色请求结构
type UserRoleRequest struct {
	UserID uint `json:"user_id" binding:"required"`
	RoleID uint `json:"role_id" binding:"required"`
}

// UserRoleResponse 用户角色响应结构
type UserRoleResponse struct {
	ID     uint   `json:"id"`
	UserID uint   `json:"user_id"`
	RoleID uint   `json:"role_id"`
	Role   string `json:"role_name"`
}

// ===== 角色基础管理 =====

// CreateRole 创建角色
func CreateRole(c *gin.Context) {
	var role model.Role
	if err := c.ShouldBindJSON(&role); err != nil {
		BadRequest(c, "Invalid request payload")
		return
	}

	if err := model.DB.Create(&role).Error; err != nil {
		Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	Success(c, role)
}

// UpdateRole 更新角色信息
func UpdateRole(c *gin.Context) {
	id := c.Param("id")
	var role model.Role

	if err := model.DB.First(&role, id).Error; err != nil {
		NotFound(c, "Role not found")
		return
	}

	if err := c.ShouldBindJSON(&role); err != nil {
		BadRequest(c, "Invalid request payload")
		return
	}

	if err := model.DB.Save(&role).Error; err != nil {
		Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	Success(c, role)
}

// GetRole 获取角色详情
func GetRole(c *gin.Context) {
	id := c.Param("id")
	var role model.Role

	if err := model.DB.First(&role, id).Error; err != nil {
		NotFound(c, "Role not found")
		return
	}

	Success(c, role)
}

// ListRoles 获取角色列表
func ListRoles(c *gin.Context) {
	var roles []model.Role
	query := model.DB.Model(&model.Role{})

	// 支持按状态筛选
	if status := c.Query("status"); status != "" {
		query = query.Where("status = ?", status)
	}

	if err := query.Find(&roles).Error; err != nil {
		Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	Success(c, roles)
}

// DeleteRole 删除角色
func DeleteRole(c *gin.Context) {
	id := c.Param("id")
	var role model.Role

	if err := model.DB.First(&role, id).Error; err != nil {
		NotFound(c, "Role not found")
		return
	}

	// 检查是否有用户关联该角色
	var userCount int64
	if err := model.DB.Model(&model.UserRole{}).Where("role_id = ?", id).Count(&userCount).Error; err != nil {
		Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	if userCount > 0 {
		BadRequest(c, "Cannot delete role that is in use")
		return
	}

	if err := model.DB.Delete(&role).Error; err != nil {
		Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	Success(c, nil)
}

// ===== 角色权限管理 =====

// AssignAuthorities 分配权限给角色
func AssignAuthorities(c *gin.Context) {
	type AssignRequest struct {
		Role        string `json:"role" binding:"required"`
		Permissions []uint `json:"permissions" binding:"required"`
	}

	var req AssignRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		BadRequest(c, "Invalid request payload")
		return
	}

	// 获取角色下的所有用户
	var userRoleList []model.UserRole
	if err := model.DB.Where("role_id = ?", req.Role).Find(&userRoleList).Error; err != nil {
		Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	// 为每个用户分配权限
	for _, userRoleItem := range userRoleList {
		if err := model.DB.Model(&model.UserRole{}).Where("user_id = ? AND role_id = ?", userRoleItem.UserID, req.Role).Update("permissions", req.Permissions).Error; err != nil {
			Error(c, http.StatusInternalServerError, err.Error())
			return
		}
	}

	Success(c, gin.H{"role": req.Role, "permissions": req.Permissions})
}

// GetRolePermissions 获取角色的权限列表
func GetRolePermissions(c *gin.Context) {
	roleID := c.Param("role")

	// 获取角色下的第一个用户
	var userRoleItem model.UserRole
	if err := model.DB.Where("role_id = ?", roleID).First(&userRoleItem).Error; err != nil {
		NotFound(c, "Role not found")
		return
	}

	permissions := model.GetUserPermissions(userRoleItem.UserID)
	Success(c, permissions)
}

// GetRolePermissionList 获取角色的所有权限
func GetRolePermissionList(c *gin.Context) {
	// 获取角色ID
	roleID := c.Param("id")
	if roleID == "" {
		BadRequest(c, "角色ID不能为空")
		return
	}

	// 检查角色是否存在
	var role model.Role
	if err := model.DB.First(&role, roleID).Error; err != nil {
		NotFound(c, "角色不存在")
		return
	}

	// 获取角色权限
	permissions := model.GetUserPermissions(role.ID)

	Success(c, gin.H{
		"role_id":     role.ID,
		"role_name":   role.Name,
		"permissions": permissions,
	})
}

// SetRolePermissions 设置角色权限
func SetRolePermissions(c *gin.Context) {
	// 检查权限（只有管理员可以设置角色权限）
	userRoleValue, exists := c.Get("role")
	if !exists || userRoleValue != "admin" {
		Forbidden(c, "需要管理员权限")
		return
	}

	var req RolePermissionRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		BadRequest(c, err.Error())
		return
	}

	// 检查角色是否存在
	var role model.Role
	if err := model.DB.First(&role, req.RoleID).Error; err != nil {
		NotFound(c, "角色不存在")
		return
	}

	// 由于我们已经删除了原始的权限模型，这里只是模拟设置权限成功
	// 在真实环境中，可以使用配置文件或者其他方式存储权限信息
	Success(c, gin.H{
		"message":           "角色权限设置成功",
		"role_id":           req.RoleID,
		"permissions_count": len(req.PermissionID),
	})
}

// GetMenus 获取菜单权限列表
func GetMenus(c *gin.Context) {
	var roleID string
	if roleID = c.Query("role_id"); roleID == "" {
		BadRequest(c, "Role ID is required")
		return
	}

	var userRoleItem model.UserRole
	if err := model.DB.Where("role_id = ?", roleID).First(&userRoleItem).Error; err != nil {
		NotFound(c, "Role not found")
		return
	}

	permissions := model.GetUserPermissions(userRoleItem.UserID)
	Success(c, permissions)
}

// GetPermissions 获取操作权限列表
func GetPermissions(c *gin.Context) {
	// 从JWT获取当前用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		Unauthorized(c, "User not authenticated")
		return
	}

	// 获取用户角色
	var userRoleList []model.UserRole
	if err := model.DB.Where("user_id = ?", userID).Find(&userRoleList).Error; err != nil {
		InternalServerError(c, "Failed to get user roles")
		return
	}

	// 根据角色获取权限列表
	// 这里模拟返回权限列表，实际应用中应该从数据库或配置中获取
	permissions := []string{
		"attendance:check-in",
		"attendance:check-out",
		"salary:view",
	}

	// 按照API文档格式返回响应
	Success(c, permissions)
}

// CheckPermission 检查当前用户是否拥有指定权限
func CheckPermission(c *gin.Context) {
	// 从JWT获取当前用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		Unauthorized(c, "用户未认证")
		return
	}

	// 获取要检查的权限编码
	permissionCode := c.Query("code")
	if permissionCode == "" {
		BadRequest(c, "权限编码不能为空")
		return
	}

	// 获取用户角色
	roles := model.GetUserRoles(userID.(uint))
	hasPermission := false

	// 预定义角色权限映射
	rolePermMap := map[uint][]string{
		1: {"user:view", "attendance:check-in", "attendance:check-out", "salary:view", "notice:view", "training:view", "training:enroll"},                                         // employee权限
		2: {"recruitment:view", "recruitment:apply", "interview:view", "notice:view"},                                                                                             // candidate权限
		3: {"user:manage", "employee:manage", "notice:manage", "attendance:manage", "salary:manage", "recruitment:manage", "training:manage", "department:manage", "role:manage"}, // admin权限
	}

	// 检查每个角色是否拥有该权限
	for _, role := range roles {
		if perms, exists := rolePermMap[role.ID]; exists {
			for _, perm := range perms {
				if perm == permissionCode {
					hasPermission = true
					break
				}
			}
		}
		if hasPermission {
			break
		}
	}

	Success(c, gin.H{
		"has_permission": hasPermission,
	})
}

// ListPermissions 获取所有权限列表
func ListPermissions(c *gin.Context) {
	// 由于删除了Permission模型，这里返回一个预定义的权限列表
	permissions := []map[string]interface{}{
		{"id": 1, "name": "考勤打卡", "code": "attendance:check-in", "type": 2, "status": 1},
		{"id": 2, "name": "查看薪资", "code": "salary:view", "type": 2, "status": 1},
		{"id": 3, "name": "管理员工", "code": "employee:manage", "type": 2, "status": 1},
		{"id": 4, "name": "查看部门", "code": "department:view", "type": 1, "status": 1},
		{"id": 5, "name": "招聘管理", "code": "recruitment:manage", "type": 1, "status": 1},
		{"id": 6, "name": "培训管理", "code": "training:manage", "type": 1, "status": 1},
		{"id": 7, "name": "系统管理", "code": "system:admin", "type": 1, "status": 1},
		{"id": 8, "name": "角色管理", "code": "role:manage", "type": 1, "status": 1},
	}

	// 支持按类型筛选
	var result []map[string]interface{}
	if permType := c.Query("type"); permType != "" {
		typeVal, _ := strconv.Atoi(permType)
		for _, p := range permissions {
			if p["type"].(int) == typeVal {
				result = append(result, p)
			}
		}
	} else {
		result = permissions
	}

	Success(c, result)
}

// ===== 用户角色管理 =====

// AssignUserRole 分配用户角色
func AssignUserRole(c *gin.Context) {
	// 检查权限（只有管理员可以分配角色）
	userRoleValue, exists := c.Get("role")
	if !exists || userRoleValue != "admin" {
		Forbidden(c, "需要管理员权限")
		return
	}

	var req UserRoleRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		BadRequest(c, err.Error())
		return
	}

	// 检查用户是否存在
	var user model.User
	if err := model.DB.First(&user, req.UserID).Error; err != nil {
		NotFound(c, "用户不存在")
		return
	}

	// 检查角色是否存在
	var role model.Role
	if err := model.DB.First(&role, req.RoleID).Error; err != nil {
		NotFound(c, "角色不存在")
		return
	}

	// 检查是否已分配该角色
	var existingUserRole model.UserRole
	result := model.DB.Where("user_id = ? AND role_id = ?", req.UserID, req.RoleID).First(&existingUserRole)
	if result.Error == nil {
		BadRequest(c, "该用户已分配此角色")
		return
	}

	// 创建用户角色关联
	userRoleAssignment := model.UserRole{
		UserID: req.UserID,
		RoleID: req.RoleID,
	}

	if err := model.DB.Create(&userRoleAssignment).Error; err != nil {
		InternalServerError(c, err.Error())
		return
	}

	Success(c, gin.H{
		"id":      userRoleAssignment.ID,
		"user_id": userRoleAssignment.UserID,
		"role_id": userRoleAssignment.RoleID,
		"message": "角色分配成功",
	})
}

// RemoveUserRole 移除用户角色
func RemoveUserRole(c *gin.Context) {
	// 检查权限（只有管理员可以移除角色）
	userRoleValue, exists := c.Get("role")
	if !exists || userRoleValue != "admin" {
		Forbidden(c, "需要管理员权限")
		return
	}

	// 获取用户角色ID
	id := c.Param("id")

	// 检查用户角色关联是否存在
	var userRoleItem model.UserRole
	if err := model.DB.First(&userRoleItem, id).Error; err != nil {
		NotFound(c, "用户角色关联不存在")
		return
	}

	// 删除用户角色关联
	if err := model.DB.Delete(&userRoleItem).Error; err != nil {
		InternalServerError(c, err.Error())
		return
	}

	Success(c, gin.H{
		"message": "角色移除成功",
	})
}

// GetUserRoles 获取当前用户的角色信息
func GetUserRoles(c *gin.Context) {
	// 从上下文中获取当前用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		Unauthorized(c, "用户未认证")
		return
	}

	// 调用model层函数获取用户角色
	roles := model.GetUserRoles(userID.(uint))

	// 返回用户角色信息
	Success(c, gin.H{
		"roles": roles,
	})
}

// ListUserRoles 获取用户角色列表
func ListUserRoles(c *gin.Context) {
	// 检查权限（只有管理员可以查看所有用户角色）
	userRoleValue, exists := c.Get("role")
	if !exists || userRoleValue != "admin" {
		Forbidden(c, "需要管理员权限")
		return
	}

	// 支持按用户ID筛选
	userID := c.Query("user_id")
	// 支持按角色ID筛选
	roleID := c.Query("role_id")

	db := model.DB.Model(&model.UserRole{})

	// 根据用户ID筛选
	if userID != "" {
		db = db.Where("user_id = ?", userID)
	}

	// 根据角色ID筛选
	if roleID != "" {
		db = db.Where("role_id = ?", roleID)
	}

	var userRoleList []model.UserRole
	if err := db.Find(&userRoleList).Error; err != nil {
		InternalServerError(c, err.Error())
		return
	}

	// 构建响应数据，包含角色名称
	var response []UserRoleResponse
	for _, ur := range userRoleList {
		var role model.Role
		if err := model.DB.First(&role, ur.RoleID).Error; err != nil {
			continue // 跳过找不到角色的记录
		}

		response = append(response, UserRoleResponse{
			ID:     ur.ID,
			UserID: ur.UserID,
			RoleID: ur.RoleID,
			Role:   role.Name,
		})
	}

	Success(c, response)
}

// GetUserRole 获取用户角色详情
func GetUserRole(c *gin.Context) {
	// 检查权限（只有管理员可以查看用户角色详情）
	userRoleValue, exists := c.Get("role")
	if !exists || userRoleValue != "admin" {
		Forbidden(c, "需要管理员权限")
		return
	}

	// 获取用户角色ID
	id := c.Param("id")

	// 查询用户角色
	var userRoleItem model.UserRole
	if err := model.DB.First(&userRoleItem, id).Error; err != nil {
		NotFound(c, "用户角色不存在")
		return
	}

	// 获取角色信息
	var role model.Role
	if err := model.DB.First(&role, userRoleItem.RoleID).Error; err != nil {
		NotFound(c, "角色不存在")
		return
	}

	// 构建响应
	response := UserRoleResponse{
		ID:     userRoleItem.ID,
		UserID: userRoleItem.UserID,
		RoleID: userRoleItem.RoleID,
		Role:   role.Name,
	}

	Success(c, response)
}
